﻿#include "FITKGraphObjectModelHighlighting.h"

// VTK
#include <vtkProperty.h>
#include <vtkAlgorithmOutput.h>
#include <vtkMapper.h>
#include <vtkDataSet.h>

// Graph
#include "FITK_Interface/FITKVTKAlgorithm/FITKGraphActor.h"
#include "FITKGraphCommons.h"

// Data
#include "FITK_Kernel/FITKCore/FITKAbstractNDataObject.h"

namespace Exchange
{
    FITKGraphObjectModelHighlighting::FITKGraphObjectModelHighlighting(AbaqusData::FITKDataCase* caseData, Core::FITKAbstractDataObject* dataObj)
        : FITKGraphObject3D(caseData, dataObj)
    {
        // Generate the actor for highlighting and add to data list.
        m_fActorHighlight = FITKGraphActor::New();
        m_fActorHighlight->setGraphObject(this);
        m_fActorHighlight->SetPickable(false);
        m_fActorHighlight->SetVisibility(false);
        m_fActorHighlight->setScalarVisibility(false);
        addActor(m_fActorHighlight);

        // Initialize properties.
        initActorProperties(m_fActorHighlight);

        // Set the layer need to be rendered.
        setRenderLayer(1);

        // Save the graph information.
        m_graphInfo.Type = OtherGraph;
    }

    void FITKGraphObjectModelHighlighting::setVisible(bool visibility)
    {
        if (m_fActorHighlight)
        {
            m_fActorHighlight->SetVisibility(visibility);
        }
    }

    void FITKGraphObjectModelHighlighting::setModelInputDataObject(vtkDataSet* dataSet)
    {
        if (!dataSet || !m_fActorHighlight)
        {
            return;
        }

        // Remove all inputs.
        vtkMapper* mapper = m_fActorHighlight->GetMapper();
        if (mapper)
        {
            mapper->RemoveAllInputs();
            mapper->RemoveAllInputConnections(0);
        }

        m_fActorHighlight->setInputDataObject(dataSet);
    }

    void FITKGraphObjectModelHighlighting::setModelInputConnection(vtkAlgorithmOutput* input, int port)
    {
        if (!input || !m_fActorHighlight)
        {
            return;
        }

        // Remove all inputs.
        vtkMapper* mapper = m_fActorHighlight->GetMapper();
        if (mapper)
        {
            mapper->RemoveAllInputs();
            mapper->RemoveAllInputConnections(0);
        }

        m_fActorHighlight->setInputConnection(input, port);
    }

    void FITKGraphObjectModelHighlighting::highlight(QColor color)
    {
        // Show the actor and change the color.
        if (m_fActorHighlight)
        {
            if (color.isValid())
            {
                double color3[3]{ 0., 0., 0. };
                FITKGraphCommons::QColorToDouble3(color, color3);
                m_fActorHighlight->GetProperty()->SetColor(color3);
            }
            else
            {
                m_fActorHighlight->GetProperty()->SetColor(1., 0., 0.);
            }

            m_fActorHighlight->SetVisibility(true);
        }

        this->Superclass::highlight();
    }

    void FITKGraphObjectModelHighlighting::disHighlight()
    {
        // Hide the actor.
        if (m_fActorHighlight)
        {
            m_fActorHighlight->SetVisibility(false);
        }

        this->Superclass::disHighlight();
    }

    void FITKGraphObjectModelHighlighting::setRepresentation(int rep)
    {
        if (!m_fActorHighlight)
        {
            return;
        }

        int repVtk = qMax(qMin(2, rep), 0);
        m_fActorHighlight->GetProperty()->SetRepresentation(repVtk);
    }

    void FITKGraphObjectModelHighlighting::setTransparency(double trans)
    {
        if (!m_fActorHighlight)
        {
            return;
        }

        double opa = qMax(qMin(1. - trans, 1.), 0.);
        m_fActorHighlight->GetProperty()->SetOpacity(opa);
    }

    void FITKGraphObjectModelHighlighting::setColor(QColor color)
    {
        if (!m_fActorHighlight)
        {
            return;
        }

        m_fActorHighlight->setColor(color);
    }

    void FITKGraphObjectModelHighlighting::initActorProperties(vtkProp* actor, QVariant details)
    {
        Q_UNUSED(details);

        if (!actor)
        {
            return;
        }

        // Set model highlighting actor properties.
        FITKGraphActor* fActor = FITKGraphActor::SafeDownCast(actor);
        if (!fActor)
        {
            return;
        }

        fActor->GetProperty()->SetEdgeVisibility(false);
        fActor->GetProperty()->SetLineWidth(3);
        fActor->GetProperty()->SetColor(1., 0., 0.);
        fActor->GetProperty()->SetRepresentation(1);
        fActor->GetProperty()->SetEdgeColor(0., 0., 0.);
    }
}   // namespace Exchange